#include "common.h"


/* Aloca um espaco de memoria */
void* memAlloc(const int size) {
    char *s;
    
    s = (char*)malloc(size);

    if (s == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    return s;
}


/* Abre um arquivo */
FILE* openFile(const char *path, const char *mode) {
    FILE *arq;

    arq = fopen(path, mode);

    if (arq == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    return arq;
}


/* Executa um comando pelo terminal */
void execComm(const char *command) {
    if (system(command) < 0) {
        perror("system");
        exit(EXIT_FAILURE);
    }
}


/* Funcao que retorna o maior entre dois inteiros */
int max(const int a, const int b) {
    if (a > b) {
        return a;
    } else {
        return b;
    }
}


/* Seta o timer para gerar um alarme */
void setTimer(const int maxExecTime) {
    struct itimerval timer;

    /* SIGALRM nao interrompe execucao */
    signal(SIGALRM, SIG_IGN);
    
    timer.it_interval.tv_usec = 0;
    timer.it_interval.tv_sec = 0;
    
    timer.it_value.tv_usec = 0;
    timer.it_value.tv_sec = maxExecTime;
    
    setitimer(ITIMER_REAL, &timer, NULL);
}


/* Insere um novo no na fila de prioridade */
void queueInsert(Node **queue, int *qSize, Node *newNode) {
    Node *tmp;
    int curr, rplc;

    queue[*qSize + 1] = newNode;
    curr = *qSize + 1;

    rplc = floor(curr/2);
    while ((rplc > 0) && (queue[curr]->lowBound < queue[rplc]->lowBound)) {
        tmp = queue[curr];
        queue[curr] = queue[rplc];
        queue[rplc] = tmp;

        curr = rplc;
        rplc = floor(curr/2);
    }

    (*qSize)++;
}


/* Remove um elemento da fila de prioridade */
Node* queueRemove(Node **queue, int *qSize, int const index) {
    Node *rm, *tmp;
    int curr, rplc;

    rm = queue[index];
    queue[index] = queue[*qSize];
    curr = index;

    while (((curr*2 <= *qSize) && (queue[curr]->lowBound > queue[curr*2]->lowBound)) || 
            ((curr*2+1 <= *qSize) && (queue[curr]->lowBound > queue[curr*2+1]->lowBound))) {

        if ((curr*2+1 <= *qSize) && (queue[curr*2]->lowBound > queue[curr*2+1]->lowBound)) {
            rplc = curr*2+1;
        } else {
            rplc = curr*2;
        }

        tmp = queue[curr];
        queue[curr] = queue[rplc];
        queue[rplc] = tmp;
    
        curr = rplc;    
    }

    (*qSize)--;
    return rm;
}


